<!--
 * @Description: 人像轨迹节点组件
 * @Author: Auto
 * @Date: 2025-01-27
-->
<template>
  <div 
    class="person-trajectory-node" 
    :class="nodeClass"
    :style="nodeStyle"
    @mousedown="handleNodeMouseDown"
    @dblclick="handleNodeDoubleClick"
  >
    <Handle id="top" type="target" position="top" />
    <Handle id="bottom" type="source" position="bottom" />
    <Handle id="left" type="target" position="left" />
    <Handle id="right" type="source" position="right" />
    
    <!-- 删除按钮 -->
    <div class="delete-btn" @click.stop="handleDelete" title="删除节点">
      <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M11 3.5L3 11.5M3 3.5L11 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
      </svg>
    </div>
    
    <!-- 调整大小拖拽点 -->
    <div 
      class="resize-handle" 
      @mousedown.stop="handleResizeStart"
      title="拖拽调整大小"
    ></div>
    
    <!-- 进度条模式 -->
    <div v-if="progress < 100" class="progress-container">
      <div class="progress-bar-wrapper">
        <div class="progress-bar" :style="{ width: `${progress}%` }"></div>
      </div>
      <div class="progress-text">{{ Math.round(progress) }}%</div>
    </div>
    
    <!-- 节点内容模式 -->
    <template v-else>
      <div class="person-trajectory-content">
        <!-- 标题 -->
        <div v-if="title" class="trajectory-title">{{ title }}</div>
        <!-- 搜索模块 -->
        <DynamicSearch
          v-if="searchFields && searchFields.length > 0"
          :search-fields="searchFields"
          @search="handleSearch"
          @reset="handleReset"
        />
        <!-- 空状态 -->
        <div v-if="!filteredData || filteredData.length === 0" class="empty-container">
          <a-empty description="暂无数据" />
        </div>
        <!-- 有数据时显示 -->
        <template v-else>
          <!-- 人像轨迹网格 -->
          <div class="trajectory-grid">
          <div 
            v-for="(item, index) in paginatedData" 
            :key="`${item.idNumber || index}-${index}`"
            class="trajectory-item"
          >
            <!-- 照片 -->
            <div class="photo-container">
              <img 
                v-if="item.photo" 
                :src="item.photo" 
                alt="人像"
                class="photo"
                @error="handleImageError"
              />
              <div v-else class="photo-placeholder">
                <span class="photo-icon">👤</span>
              </div>
            </div>
            
            <!-- 证件号 -->
            <div 
              v-if="item.idNumber" 
              class="id-number id-card-display"
              :title="item.idNumber"
              draggable="true"
              @mousedown.stop="handleIdCardMouseDown"
              @dragstart="handleIdCardDragStart"
              @dragend="handleIdCardDragEnd"
            >
              <svg t="1763026344096" class="icon id-card-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1615" width="12" height="12">
                <path d="M864.65 336.975v-0.079c56.91 0 98.58 45.804 98.58 102.321v204.485c0 193.26-26.94 349.932-317.283 349.932-127.055 0-187.156-25.363-239.616-68.135a103.778 103.778 0 0 1-19.377-14.966L99.249 624.64c-48.994-49.034-26.584-117.957 7.759-152.222 34.265-34.343 105.433-39.975 145.723 0l62.425 62.307V137.689a102.676 102.676 0 0 1 103.03-102.243c56.91 0 99.643 45.726 99.643 102.243v103.817a102.4 102.4 0 0 1 48.6-12.209c45.293 0 80.463 29.066 94.287 69.317 15.754-9.728 34.856-15.517 54.863-15.517 45.292 0 80.384 29.065 94.208 69.395a95.31 95.31 0 0 1 52.145-15.517h2.757z m44.19 306.727v0.158h0.236V445.755c0-50.333-47.301-48.364-47.301-48.364-26.94 0-46.986 21.661-46.986 48.364v106.417h-0.551a31.114 31.114 0 0 1 0.55 5.435 26.466 26.466 0 0 1-26.544 26.86 27.018 27.018 0 0 1-26.546-32.295h-0.55v-156.12c0-45.332-48.76-48.404-48.76-48.404-26.938 0-46.08 21.7-46.08 48.404v123.943h-0.63a26.978 26.978 0 0 1-26.505 32.295 27.018 27.018 0 0 1-26.545-32.295h-0.552V342.37c0-49.112-47.773-48.443-47.773-48.443-26.94 0-46.474 21.662-46.474 48.443v134.538h-0.512a26.978 26.978 0 0 1-26.624 32.296 27.018 27.018 0 0 1-26.545-32.296h-0.512v-328.35c0-26.702-18.432-48.442-45.371-48.442-27.018 0-48.837 21.74-48.837 48.443v516.214c-49.231-48.837-98.383-97.753-147.535-146.629-19.062-18.905-55.257-18.196-74.949 1.575-19.653 19.693-25.758 50.452-1.694 74.595l272.306 270.533c50.53 50.176 117.248 74.91 228.234 74.91 262.262 0 263.05-132.53 263.05-296.055z" p-id="1616" fill="#1890ff"></path>
              </svg>
              <span class="id-card-text">{{ item.idNumber }}</span>
            </div>
            <div v-else class="id-number">未设置</div>
            
            <!-- 时间 -->
            <div class="time" :title="item.time">
              {{ item.time || '未设置' }}
            </div>
            
            <!-- 地点 -->
            <div class="location" :title="item.location">
              {{ item.location || '未设置' }}
            </div>
          </div>
        </div>
        
          <!-- 分页 -->
          <div class="pagination" v-if="total > 0">
          <div class="pagination-left">
            <span class="total-info">共 {{ total }} 条</span>
            <span class="divider">|</span>
            <span class="page-size-label">每页</span>
            <select 
              class="page-size-select"
              :value="pageSize"
              @change="handlePageSizeChange(Number(($event.target as HTMLSelectElement).value))"
            >
              <option v-for="option in pageSizeOptions" :key="option" :value="option">
                {{ option }}
              </option>
            </select>
            <span class="page-size-label">条</span>
          </div>
          <div class="pagination-right" v-if="totalPages > 1">
            <button 
              class="page-btn"
              :disabled="currentPage === 1"
              @click="goToPage(currentPage - 1)"
            >
              上一页
            </button>
            <span class="page-info">
              第 {{ currentPage }} / {{ totalPages }} 页
            </span>
            <button 
              class="page-btn"
              :disabled="currentPage === totalPages"
              @click="goToPage(currentPage + 1)"
            >
              下一页
            </button>
          </div>
          </div>
        </template>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, onUnmounted } from 'vue'
import { Handle } from '@vue-flow/core'
import DynamicSearch, { type SearchField } from './DynamicSearch.vue'
import dayjs from 'dayjs'

Handle.name = 'Handle'

interface TrajectoryItem {
  photo?: string // 照片URL
  idNumber?: string // 证件号码
  time?: string // 时间
  location?: string // 地点
}

interface Props {
  data?: TrajectoryItem[] // 人像轨迹数据
  itemsPerPage?: number // 每页显示数量，默认10（2行x5列）
  title?: string // 标题
  progress?: number // 进度 0-100
  nodeId?: string
  width?: number
  height?: number
  searchFields?: SearchField[] // 搜索字段配置
  selected?: boolean // 是否选中
}

const props = withDefaults(defineProps<Props>(), {
  data: () => [],
  itemsPerPage: 10, // 默认2行x5列=10个
  title: '',
  progress: 100,
  nodeId: '',
  width: undefined,
  height: undefined,
  searchFields: () => [],
  selected: false
})

const emit = defineEmits<{
  delete: [nodeId: string]
  resize: [nodeId: string, width: number, height: number]
}>()

// 搜索相关
const searchValues = ref<Record<string, any>>({})

// 过滤后的数据
const filteredData = computed(() => {
  if (!props.data || props.data.length === 0) return []
  if (!searchValues.value || Object.keys(searchValues.value).length === 0) return props.data
  
  // 分离时间范围字段和普通字段
  const timeRangeFields: Record<string, { start?: string; end?: string }> = {}
  const normalFields: Record<string, any> = {}
  
  Object.keys(searchValues.value).forEach(key => {
    const value = searchValues.value[key]
    if (value === null || value === undefined || value === '') {
      return
    }
    
    if (key.endsWith('Start')) {
      const fieldKey = key.replace(/Start$/, '')
      if (!timeRangeFields[fieldKey]) {
        timeRangeFields[fieldKey] = {}
      }
      timeRangeFields[fieldKey].start = value
    } else if (key.endsWith('End')) {
      const fieldKey = key.replace(/End$/, '')
      if (!timeRangeFields[fieldKey]) {
        timeRangeFields[fieldKey] = {}
      }
      timeRangeFields[fieldKey].end = value
    } else {
      normalFields[key] = value
    }
  })
  
  return props.data.filter(item => {
    // 检查时间范围字段
    for (const fieldKey in timeRangeFields) {
      const range = timeRangeFields[fieldKey]
      const fieldValue = item[fieldKey]
      if (!fieldValue) {
        if (range.start || range.end) return false
        continue
      }
      
      const itemDate = dayjs(fieldValue)
      
      if (range.start) {
        const startDate = dayjs(range.start)
        if (itemDate.isBefore(startDate, 'day')) return false
      }
      
      if (range.end) {
        const endDate = dayjs(range.end)
        if (itemDate.isAfter(endDate, 'day')) return false
      }
    }
    
    // 检查普通字段
    for (const key in normalFields) {
      const searchValue = normalFields[key]
      const itemValue = String(item[key] || '').toLowerCase()
      const searchStr = String(searchValue).toLowerCase()
      if (!itemValue.includes(searchStr)) {
        return false
      }
    }
    
    return true
  })
})

// 分页相关
const currentPage = ref(1)
const pageSize = ref(5) // 每页显示数量，默认5个（一行5个）
// 照片固定尺寸 - 增加宽度以适应证件号
const PHOTO_WIDTH = 130 // 增加照片宽度以适应证件号
const PHOTO_HEIGHT = 126 // 保持高度126px
const PHOTO_GAP = 12 // 照片之间的间距
const CONTAINER_PADDING = 24 // 容器内边距（左右各12px）

// 根据节点宽度动态计算每行可容纳的照片数量
const itemsPerRow = computed(() => {
  if (!props.width) return 5 // 默认5个
  // 可用宽度 = 节点宽度 - 容器内边距
  const availableWidth = props.width - CONTAINER_PADDING
  // 轨迹项宽度 = 照片宽度130px + 左右边距16px（8px * 2）
  const itemWidth = PHOTO_WIDTH + 16
  // 每行数量 = (可用宽度 + 间距) / (轨迹项宽度 + 间距)
  const cols = Math.floor((availableWidth + PHOTO_GAP) / (itemWidth + PHOTO_GAP))
  return Math.max(1, cols) // 至少1列
})

// 计算总数
const total = computed(() => {
  return filteredData.value?.length || 0
})

// 计算总页数
const totalPages = computed(() => {
  return Math.ceil(total.value / pageSize.value)
})

// 计算当前页的数据
const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredData.value?.slice(start, end) || []
})

// 处理搜索
const handleSearch = (values: Record<string, any>) => {
  searchValues.value = values
  currentPage.value = 1
}

// 处理重置
const handleReset = () => {
  searchValues.value = {}
  currentPage.value = 1
}

// 每页数量选项
const pageSizeOptions = [5, 10, 20, 50]

// 处理每页数量变化
const handlePageSizeChange = (newSize: number) => {
  pageSize.value = newSize
  currentPage.value = 1 // 重置到第一页
}

// 跳转到指定页
const goToPage = (page: number) => {
  if (page >= 1 && page <= totalPages.value) {
    currentPage.value = page
  }
}

// 监听数据变化，重置到第一页
watch(() => props.data, () => {
  currentPage.value = 1
}, { deep: true })

// 监听搜索值变化，重置到第一页
watch(() => searchValues.value, () => {
  currentPage.value = 1
}, { deep: true })

// 节点样式
const nodeClass = computed(() => {
  return {
    'node-loading': props.progress < 100,
    'node-selected': props.selected
  }
})

const nodeStyle = computed(() => {
  const style: any = {}
  if (props.width) {
    style.width = `${props.width}px`
    // 设置CSS变量，用于动态计算列数
    style['--items-per-row'] = itemsPerRow.value
  }
  if (props.height) {
    style.height = `${props.height}px`
  }
  return style
})

// 处理删除
const handleDelete = () => {
  if (props.nodeId) {
    emit('delete', props.nodeId)
  }
}

// 处理调整大小
let isResizing = false
let startX = 0
let startY = 0
let startWidth = 0
let startHeight = 0

const handleResizeStart = (e: MouseEvent) => {
  if (!props.width || !props.height) return
  
  e.preventDefault()
  e.stopPropagation()
  isResizing = true
  startX = e.clientX
  startY = e.clientY
  startWidth = props.width
  startHeight = props.height
  
  document.addEventListener('mousemove', handleResizeMove)
  document.addEventListener('mouseup', handleResizeEnd)
  document.body.style.userSelect = 'none'
  document.body.style.cursor = 'nwse-resize'
}

const handleResizeMove = (e: MouseEvent) => {
  if (!isResizing) return
  
  const deltaX = e.clientX - startX
  const deltaY = e.clientY - startY
  
  const MIN_WIDTH = 802 // 最小宽度802px（一行5个：146px * 5 + 12px * 4 + 24px）
  const MIN_HEIGHT = 400 // 最小高度400px
  const MAX_HEIGHT = 800 // 最大高度800px，防止无限拉伸
  
  const newWidth = Math.max(MIN_WIDTH, startWidth + deltaX)
  const newHeight = Math.max(MIN_HEIGHT, Math.min(MAX_HEIGHT, startHeight + deltaY)) // 限制在最小和最大高度之间
  
  if (props.nodeId) {
    emit('resize', props.nodeId, newWidth, newHeight)
  }
}

const handleResizeEnd = () => {
  isResizing = false
  document.removeEventListener('mousemove', handleResizeMove)
  document.removeEventListener('mouseup', handleResizeEnd)
  document.body.style.userSelect = ''
  document.body.style.cursor = ''
}

onUnmounted(() => {
  document.removeEventListener('mousemove', handleResizeMove)
  document.removeEventListener('mouseup', handleResizeEnd)
})

// 处理图片加载错误
const handleImageError = (e: Event) => {
  const img = e.target as HTMLImageElement
  img.style.display = 'none'
}

// 处理节点鼠标按下事件 - 确保拖拽功能正常
const handleNodeMouseDown = (e: MouseEvent) => {
  // 如果点击的是按钮、调整大小拖拽点或Handle，不阻止事件
  const target = e.target as HTMLElement
  if (
    target.closest('.delete-btn') ||
    target.closest('.resize-handle') ||
    target.closest('.vue-flow__handle') ||
    target.closest('.pagination') ||
    target.closest('.id-card-display')
  ) {
    return
  }
  // 其他区域允许拖拽，不阻止默认行为
}

// 处理节点双击事件
const handleNodeDoubleClick = (e: MouseEvent) => {
  // 如果点击的是按钮、调整大小拖拽点或Handle，不处理双击
  const target = e.target as HTMLElement
  if (
    target.closest('.delete-btn') ||
    target.closest('.resize-handle') ||
    target.closest('.vue-flow__handle') ||
    target.closest('.pagination') ||
    target.closest('.id-card-display')
  ) {
    return
  }
  console.log('Node double clicked in component:', props.nodeId)
}

// 处理身份证号码鼠标按下事件 - 阻止节点拖拽
const handleIdCardMouseDown = (e: MouseEvent) => {
  e.stopPropagation() // 阻止事件冒泡，防止触发节点拖拽
  console.log('身份证号码 mousedown', { target: e.target })
}

// 处理身份证号码拖拽开始
const handleIdCardDragStart = (e: DragEvent) => {
  console.log('身份证号码拖拽开始', { target: e.target })
  
  // 阻止节点拖拽，但不阻止拖拽事件本身
  e.stopPropagation() // 阻止冒泡到节点
  
  const target = e.target as HTMLElement
  const idCardElement = target.closest('.id-card-display') as HTMLElement
  if (!idCardElement || !e.dataTransfer) {
    console.log('没有身份证号码元素或 dataTransfer')
    e.preventDefault()
    return false
  }
  
  // 获取证件号码文本
  const idCardText = idCardElement.querySelector('.id-card-text')?.textContent
  if (!idCardText) {
    console.log('没有证件号码文本')
    e.preventDefault()
    return false
  }
  
  // 设置拖拽数据
  e.dataTransfer.effectAllowed = 'copy'
  e.dataTransfer.setData('text/plain', idCardText)
  e.dataTransfer.setData('application/id-card', idCardText)
  e.dataTransfer.setData('source-node-id', props.nodeId || '')
  
  console.log('拖拽数据已设置', { 
    idCard: idCardText,
    types: e.dataTransfer.types,
    effectAllowed: e.dataTransfer.effectAllowed 
  })
  
  // 添加拖拽时的视觉反馈
  idCardElement.style.opacity = '0.5'
  
  // 不要返回 false，让拖拽继续
}

// 处理身份证号码拖拽结束
const handleIdCardDragEnd = (e: DragEvent) => {
  // 恢复视觉反馈
  const target = e.target as HTMLElement
  const idCardElement = target.closest('.id-card-display') as HTMLElement
  if (idCardElement) {
    idCardElement.style.opacity = '1'
  }
  
  console.log('拖拽结束')
}
</script>

<style scoped lang="less">
.person-trajectory-node {
  padding: 10px 8px;
  border-radius: 8px;
  min-width: 802px; // 一行5个的最小宽度：146px * 5 + 12px * 4 + 24px = 802px
  width: 850px; // 默认宽度，增加以完整展示数据
  min-height: 400px;
  height: 500px;
  background: #ffffff;
  border: 2px solid #1890ff; // 改为蓝色，与其他组件保持一致
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
  cursor: grab; // 与其他组件保持一致
  position: relative;
  overflow: visible;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  
  &:active {
    cursor: grabbing; // 拖拽时显示grabbing
  }
  
  &.node-loading {
    pointer-events: none;
  }

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }

  // 选中状态样式
  &.node-selected {
    border-color: #1890ff;
    border-width: 3px;
    box-shadow: 0 0 0 3px rgba(24, 144, 255, 0.2), 0 4px 16px rgba(24, 144, 255, 0.3);
  }

  :deep(.vue-flow__handle) {
    width: 4px !important;
    height: 4px !important;
    background: #1890ff !important; // 改为蓝色
    border: 2px solid #ffffff !important;
    border-radius: 50% !important;
    z-index: 1000 !important;
    opacity: 0.9;
    cursor: crosshair !important;
    pointer-events: auto !important;
    padding: 4px !important;
    margin: -4px !important;
    box-sizing: content-box !important;
    position: absolute !important;

    &:hover {
      opacity: 1 !important;
      background: #40a9ff !important; // 改为蓝色hover状态
      box-shadow: 0 0 8px rgba(24, 144, 255, 0.6) !important;
      z-index: 1001 !important;
    }
  }

  .delete-btn {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 4px;
    cursor: pointer;
    z-index: 1002;
    opacity: 1; // 一直显示，与其他组件保持一致
    transition: background-color 0.2s ease;
    color: #8c8c8c;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

    &:hover {
      background: #ff4d4f;
      color: #ffffff;
    }
  }

  .resize-handle {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 12px;
    height: 12px;
    background: #1890ff; // 改为蓝色
    border: 2px solid #ffffff;
    border-radius: 50%;
    cursor: nwse-resize;
    z-index: 1002;
    opacity: 0;
    transition: opacity 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
    transform: translate(50%, 50%); // 与其他组件保持一致

    &:hover {
      opacity: 1 !important;
      background: #40a9ff; // 改为蓝色hover状态
      box-shadow: 0 0 8px rgba(24, 144, 255, 0.6);
    }

    &:active {
      background: #0050b3; // 改为蓝色active状态
    }
  }

  &:hover .resize-handle {
    opacity: 0.8;
  }
}

// 进度条
.progress-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 20px;
  
  .progress-bar-wrapper {
    width: 80%;
    height: 8px;
    background: #f0f0f0;
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 12px;
    
    .progress-bar {
      height: 100%;
      background: linear-gradient(90deg, #1890ff, #40a9ff);
      transition: width 0.3s ease;
    }
  }
  
  .progress-text {
    font-size: 14px;
    color: #666;
    font-weight: 500;
  }
}

// 节点内容
.person-trajectory-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 12px;
  box-sizing: border-box;
  overflow: hidden;
}

// 空状态容器
.empty-container {
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 20px;
}

// 标题样式 - 与人员列表一致
.trajectory-title {
  font-size: 16px;
  font-weight: 600;
  color: #1890ff; // 蓝色，与人像轨迹节点颜色一致
  text-align: center;
  padding: 8px 0;
  margin-bottom: 8px;
  flex-shrink: 0;
  border-bottom: 1px solid #e8e8e8;
}

// 搜索模块样式
:deep(.dynamic-search) {
  flex-shrink: 0;
}

// 轨迹网格 - 使用动态列数
.trajectory-grid {
  display: grid;
  grid-template-columns: repeat(var(--items-per-row), 146px); // 使用CSS变量，每列固定146px（130px照片 + 16px左右边距）
  gap: 12px;
  flex: 1;
  overflow-y: auto;
  padding: 0 12px 8px 12px; // 添加左右边距
  justify-content: start; // 左对齐
}

// 轨迹项 - 固定宽度，不随容器拉伸
.trajectory-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0; // 去掉padding，照片容器的margin会提供间距
  background: #fafafa;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  transition: all 0.2s;
  width: 146px; // 130px照片 + 16px左右边距（8px * 2）
  min-height: 200px; // 根据照片高度126px + 证件号 + 时间 + 地点调整
  max-height: 250px; // 限制最大高度，防止无限拉伸
  box-sizing: border-box;
  flex-shrink: 0; // 不缩放
  overflow: hidden; // 防止内容溢出
  
  &:hover {
    border-color: #1890ff;
    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);
  }
}

// 照片容器 - 固定130*126尺寸（增加宽度以适应证件号）
.photo-container {
  width: 130px; // 固定宽度130px（增加宽度以适应证件号）
  height: 126px; // 固定高度126px
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px; // 上下左右都是8px外边距
  overflow: hidden;
  border-radius: 8px; // 添加圆角
  background: #f0f0f0;
  flex-shrink: 0; // 不缩放
  
  .photo {
    width: 100%;
    height: 100%;
    object-fit: cover; // 等比例缩放，保持宽高比，裁剪多余部分
    object-position: center;
  }
  
  .photo-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f0f0f0;
    
    .photo-icon {
      font-size: 60px; // 增大图标以适应更大的容器
      opacity: 0.5;
    }
  }
}

// 证件号
.id-number {
  width: 100%;
  font-size: 11px; // 稍微减小字体以适应宽度
  color: #1890ff;
  font-weight: 500;
  text-align: center;
  margin-bottom: 6px;
  padding: 0 4px; // 减小左右内边距以适应宽度
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
  flex-shrink: 0; // 不缩放
  box-sizing: border-box;
  max-width: 100%; // 确保不超出容器宽度
  
  // 可拖拽的证件号样式
  &.id-card-display {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    cursor: grab;
    user-select: none;
    transition: opacity 0.2s ease;
    position: relative;
    z-index: 10;
    pointer-events: auto;
    
    &:hover {
      opacity: 0.8;
    }
    
    &:active {
      cursor: grabbing;
    }
    
    .id-card-icon {
      display: inline-block;
      vertical-align: middle;
      flex-shrink: 0;
      
      path {
        fill: #1890ff;
      }
    }
    
    .id-card-text {
      color: #1890ff;
      font-weight: 500;
      flex-shrink: 0;
    }
    
    // 确保内部的 SVG 和文本也能触发拖拽
    svg,
    .id-card-text {
      pointer-events: none; // 让事件冒泡到父元素
    }
  }
}

// 时间
.time {
  width: 100%;
  font-size: 12px;
  color: #666;
  text-align: center;
  margin-bottom: 6px;
  padding: 0 8px; // 添加左右内边距
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
  flex-shrink: 0; // 不缩放
  box-sizing: border-box;
}

// 地点
.location {
  width: 100%;
  font-size: 12px;
  color: #333;
  text-align: center;
  line-height: 1.4;
  word-wrap: break-word;
  word-break: break-all;
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 2; // 最多显示2行
  -webkit-box-orient: vertical;
  overflow: hidden;
  padding: 0 8px; // 添加左右内边距
  margin-bottom: 8px; // 添加下边距
  flex: 1;
  min-height: 0; // 允许缩小
  max-height: 34px; // 限制最大高度为2行（12px * 1.4 * 2）
  box-sizing: border-box;
}

// 分页
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-top: 1px solid #e8e8e8;
  margin-top: 8px;
  
  .pagination-left {
    display: flex;
    align-items: center;
    gap: 8px;
    
    .total-info {
      font-size: 12px;
      color: #666;
    }
    
    .divider {
      font-size: 12px;
      color: #d9d9d9;
    }
    
    .page-size-label {
      font-size: 12px;
      color: #666;
    }
    
    .page-size-select {
      padding: 2px 8px;
      border: 1px solid #d9d9d9;
      border-radius: 4px;
      background: #ffffff;
      font-size: 12px;
      color: #333;
      cursor: pointer;
      outline: none;
      transition: all 0.2s;
      
      &:hover {
        border-color: #1890ff;
      }
      
      &:focus {
        border-color: #1890ff;
        box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
      }
    }
  }
  
  .pagination-right {
    display: flex;
    align-items: center;
    gap: 16px;
  }
  
  .page-btn {
    padding: 4px 12px;
    border: 1px solid #d9d9d9;
    background: #ffffff;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: #333;
    transition: all 0.2s;
    
    &:hover:not(:disabled) {
      border-color: #1890ff;
      color: #1890ff;
    }
    
    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
  
  .page-info {
    font-size: 12px;
    color: #666;
    min-width: 80px;
    text-align: center;
  }
}

// 滚动条样式
.trajectory-grid::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.trajectory-grid::-webkit-scrollbar-track {
  background: #f0f0f0;
  border-radius: 3px;
}

.trajectory-grid::-webkit-scrollbar-thumb {
  background: #d9d9d9;
  border-radius: 3px;
  
  &:hover {
    background: #bfbfbf;
  }
}
</style>

